<!DOCTYPE html>
<html lang="en">

<head>
	<base href="$$.RootPath$$">
	<title>Shiori - Bookmarks Manager</title>

	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">

	<link rel="apple-touch-icon-precomposed" sizes="152x152" href="assets/res/apple-touch-icon-152x152.png">
	<link rel="apple-touch-icon-precomposed" sizes="144x144" href="assets/res/apple-touch-icon-144x144.png">
	<link rel="icon" type="image/png" href="assets/res/favicon-32x32.png" sizes="32x32">
	<link rel="icon" type="image/png" href="assets/res/favicon-16x16.png" sizes="16x16">
	<link rel="icon" type="image/x-icon" href="assets/res/favicon.ico">
	<link rel="manifest" href="assets/manifest.webmanifest" />

	<link href="assets/css/style.css" rel="stylesheet">

	<script src="assets/js/vue.min.js" type="text/javascript"></script>
	<script src="assets/js/url.min.js" type="text/javascript"></script>
</head>

<body>
	<div id="app">
		<login-view v-if="isLoggedIn === false && loginRequired" @login-success="onLoginSuccess"></login-view>
		<div id="main-scene" v-else-if="isLoggedIn === true">
    		<div id="main-sidebar">
    			<a v-for="item in sidebarItems" :title="item.title" :class="{active: activePage === item.page}" @click="switchPage(item.page)">
    				<i class="fas fa-fw" :class="item.icon"></i>
    			</a>
    			<div class="spacer"></div>
    			<a title="Logout" @click="logout">
    				<i class="fas fa-fw fa-sign-out-alt"></i>
    			</a>
    		</div>
    		<keep-alive>
    			<component :is="activePage" :active-account="activeAccount" :app-options="appOptions" @setting-changed="saveSetting"></component>
    		</keep-alive>
    		<custom-dialog v-bind="dialog"></custom-dialog>
		</div>
	</div>

	<script type="module">
		import basePage from "./assets/js/page/base.js";
		import LoginComponent from "./assets/js/component/login.js";
		import pageHome from "./assets/js/page/home.js";
		import pageSetting from "./assets/js/page/setting.js";
		import customDialog from "./assets/js/component/dialog.js";
        import EventBus from "./assets/js/component/eventBus.js";
        Vue.prototype.$bus = EventBus;

		var app = new Vue({
			el: '#app',
			mixins: [basePage],
			components: {
				pageHome,
				pageSetting,
				customDialog,
				'login-view': LoginComponent
			},
			data: {
				isLoggedIn: null,
				loginRequired: false,
				activePage: "page-home",
				sidebarItems: [{
					title: "Home",
					icon: "fa-home",
					page: "page-home",
				}, {
					title: "Settings",
					icon: "fa-cog",
					page: "page-setting",
				}],
			},
			methods: {
				switchPage(page) {
					var pageName = page.replace("page-", ""),
						state = { activePage: page },
						url = new Url;

                    if (page === 'page-home'  && this.activePage === 'page-home') {
                        Vue.prototype.$bus.$emit('clearHomePage', {});
                    }
					url.hash = pageName;
					this.activePage = page;
					history.pushState(state, page, url);
				},
				logout() {
					this.showDialog({
						title: "Log Out",
						content: "Are you sure you want to log out ?",
						mainText: "Yes",
						secondText: "No",
						mainClick: () => {
							this.dialog.loading = true;
							fetch(new URL("api/v1/auth/logout", document.baseURI), {
								method: "post"
							}).then(response => {
								if (!response.ok) throw response;
								return response;
							}).then(() => {
								localStorage.removeItem("shiori-account");
								localStorage.removeItem("shiori-token");
								document.cookie = `session-id=; Path=${new URL(document.baseURI).pathname}; Expires=Thu, 01 Jan 1970 00:00:00 GMT;`;
								document.cookie = `token=; Path=${new URL(document.baseURI).pathname}; Expires=Thu, 01 Jan 1970 00:00:00 GMT;`;
								this.isLoggedIn = false;
								this.loginRequired = true;
								this.dialog.loading = false;
								this.dialog.visible = false;
							}).catch(err => {
								this.dialog.loading = false;
								this.getErrorMessage(err).then(msg => {
									this.showErrorDialog(msg);
								})
							});
						}
					});
				},
				saveSetting(opts) {
					this.appOptions = opts;
                    this.themeSwitch(opts.Theme)
				},
				loadSetting() {
					var opts = JSON.parse(localStorage.getItem("shiori-account")) || {},
						ShowId = (typeof opts.config.ShowId === "boolean") ? opts.config.ShowId : false,
						ListMode = (typeof opts.config.ListMode === "boolean") ? opts.config.ListMode : false,
						HideThumbnail = (typeof opts.config.HideThumbnail === "boolean") ? opts.config.HideThumbnail : false,
						HideExcerpt = (typeof opts.config.HideExcerpt === "boolean") ? opts.config.HideExcerpt : false,
                        Theme = (typeof opts.config.Theme === "string" && opts.config.Theme !== "") ? opts.config.Theme : "follow",
						KeepMetadata = (typeof opts.config.KeepMetadata === "boolean") ? opts.config.KeepMetadata : false,
						UseArchive = (typeof opts.config.UseArchive === "boolean") ? opts.config.UseArchive : false,
						CreateEbook = (typeof opts.config.CreateEbook === "boolean") ? opts.config.CreateEbook : false,
						MakePublic = (typeof opts.config.MakePublic === "boolean") ? opts.config.MakePublic : false;

					this.appOptions = {
						ShowId: ShowId,
						ListMode: ListMode,
						HideThumbnail: HideThumbnail,
						HideExcerpt: HideExcerpt,
						Theme: Theme,
						KeepMetadata: KeepMetadata,
						UseArchive: UseArchive,
						CreateEbook: CreateEbook,
						MakePublic: MakePublic,
					};
                    this.themeSwitch(Theme)
				},
				loadAccount() {
					var account = JSON.parse(localStorage.getItem("shiori-account")) || {},
						id = (typeof account.id === "number") ? account.id : 0,
						username = (typeof account.username === "string") ? account.username : "",
						owner = (typeof account.owner === "boolean") ? account.owner : false;

					this.activeAccount = {
						id: id,
						username: username,
						owner: owner,
					};
				},

				onLoginSuccess() {
					this.loadAccount();
					this.loadSetting();
					this.isLoggedIn = true;
				},

				async validateSession() {
					const token = localStorage.getItem("shiori-token");
					const account = localStorage.getItem("shiori-account");

					try {
						const response = await fetch(new URL("api/v1/auth/me", document.baseURI), {
							headers: {
								"Authorization": `Bearer ${token}`
							}
						});

						if (!response.ok) {
							throw new Error('Invalid session');
						}

						const responseJSON = await response.json();
						localStorage.setItem(
							"shiori-account",
							JSON.stringify(responseJSON.message),
						);
						return true;
					} catch (err) {
						// Clear invalid session data
						localStorage.removeItem("shiori-account");
						localStorage.removeItem("shiori-token");
						document.cookie = `session-id=; Path=${new URL(document.baseURI).pathname}; Expires=Thu, 01 Jan 1970 00:00:00 GMT;`;
						document.cookie = `token=; Path=${new URL(document.baseURI).pathname}; Expires=Thu, 01 Jan 1970 00:00:00 GMT;`;
						return false;
					}
				},

				async checkLoginStatus() {
					const isValid = await this.validateSession();
					this.isLoggedIn = isValid;

					if (isValid) {
						this.loadSetting();
						this.loadAccount();
					} else {
						this.loginRequired = true;
					}
				}
			},
			async mounted() {
				await this.checkLoginStatus();
				if (this.isLoggedIn) {
					this.loadSetting();
					this.loadAccount();
				}

				// Prepare history state watcher
				var stateWatcher = (e) => {
					var state = e.state || {};
					this.activePage = state.activePage || "page-home";
				}

				window.addEventListener('popstate', stateWatcher);
				this.$once('hook:beforeDestroy', function () {
					window.removeEventListener('popstate', stateWatcher);
				})

				// Set initial active page
				var initialPage = (new Url).hash || "home";
				if (initialPage === "home" || initialPage === "setting") {
					this.activePage = `page-${initialPage}`;
				} else {
					history.replaceState(null, "page-home", "/#home");
				}
			}
		})
	</script>
</body>

</html>
